package com.agileboot.attendance.domain.overtime.model;

import com.agileboot.attendance.common.enums.OvertimeStatusEnum;
import com.agileboot.attendance.domain.overtime.db.entity.AttOvertimeEntity;
import com.agileboot.attendance.domain.overtime.db.service.IOvertimeService;
import com.agileboot.attendance.domain.overtime.dto.OvertimeRequest;
import com.agileboot.common.exception.ApiException;
import com.agileboot.common.exception.error.ErrorCode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import org.springframework.beans.BeanUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 加班申请模型
 */
@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public class OvertimeModel extends AttOvertimeEntity {

    private static final String ERROR_MSG_NOT_FOUND = "加班申请不存在";
    private static final String ERROR_MSG_STATUS_INVALID = "加班申请状态不正确";
    private static final String ERROR_MSG_DURATION_INVALID = "加班时长不能小于等于0";
    private static final String ERROR_MSG_TIME_INVALID = "加班结束时间必须晚于开始时间";

    private IOvertimeService overtimeService;

    public OvertimeModel(AttOvertimeEntity entity, IOvertimeService overtimeService) {
        if (entity == null) {
            throw new ApiException(ErrorCode.Business.COMMON_OBJECT_NOT_FOUND, "加班申请");
        }
        BeanUtils.copyProperties(entity, this);
        this.overtimeService = overtimeService;
    }

    public OvertimeModel(OvertimeRequest request) {
        this.setEmployeeId(request.getEmployeeId());
        this.setEmployeeName(request.getEmployeeName());
        this.setDeptId(request.getDeptId());
        this.setDeptName(request.getDeptName());
        this.setOvertimeType(request.getOvertimeType());
        this.setStartTime(request.getStartTime());
        this.setEndTime(request.getEndTime());
        this.setDuration(new BigDecimal(request.getDuration()));
        this.setReason(request.getReason());
        this.setStatus(OvertimeStatusEnum.PENDING.getValue());
    }

    /**
     * 审批通过
     *
     * @param approverId   审批人ID
     * @param approverName 审批人姓名
     * @param remark      审批备注
     */
    public void approve(Long approverId, String approverName, String remark) {
        if (!OvertimeStatusEnum.PENDING.getValue().equals(this.getStatus())) {
            throw new ApiException(ErrorCode.Business.COMMON_UNSUPPORTED_OPERATION, "只能审批待审批状态的加班申请");
        }
        this.setStatus(OvertimeStatusEnum.APPROVED.getValue());
        this.setApproverId(approverId);
        this.setApproverName(approverName);
        this.setApproveTime(LocalDateTime.now());
        this.setApproveRemark(remark);
        
        overtimeService.updateById(this);
    }

    /**
     * 审批拒绝
     *
     * @param approverId   审批人ID
     * @param approverName 审批人姓名
     * @param remark      审批备注
     */
    public void reject(Long approverId, String approverName, String remark) {
        if (!OvertimeStatusEnum.PENDING.getValue().equals(this.getStatus())) {
            throw new ApiException(ErrorCode.Business.COMMON_UNSUPPORTED_OPERATION, "只能审批待审批状态的加班申请");
        }
        this.setStatus(OvertimeStatusEnum.REJECTED.getValue());
        this.setApproverId(approverId);
        this.setApproverName(approverName);
        this.setApproveTime(LocalDateTime.now());
        this.setApproveRemark(remark);
        
        overtimeService.updateById(this);
    }

    /**
     * 取消申请
     */
    public void cancel() {
        if (!OvertimeStatusEnum.PENDING.getValue().equals(this.getStatus())) {
            throw new ApiException(ErrorCode.Business.COMMON_UNSUPPORTED_OPERATION, "只能取消待审批状态的加班申请");
        }
        this.setStatus(OvertimeStatusEnum.CANCELLED.getValue());
        
        overtimeService.updateById(this);
    }

    /**
     * 验证加班时间
     */
    public void validateTime() {
        if (this.getStartTime().isAfter(this.getEndTime())) {
            throw new ApiException(ErrorCode.Business.COMMON_UNSUPPORTED_OPERATION, "加班开始时间不能晚于结束时间");
        }
        if (this.getStartTime().isBefore(LocalDateTime.now())) {
            throw new ApiException(ErrorCode.Business.COMMON_UNSUPPORTED_OPERATION, "加班开始时间不能早于当前时间");
        }
    }
} 